package top.lishuoboy.javaweb.a13cookie_session; /**
 * @author lishuoboy
 * @date 2022-01-10 20:54
 */

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@Slf4j
@WebServlet(name = "SessionServlet", value = "/SessionServlet")
public class SessionServlet extends BaseServlet {
    /**
     * i) 什么是 Session 会话?
     * 1、Session 就一个接口（HttpSession）。
     * 2、Session 就是会话。它是用来维护一个客户端和服务器之间关联的一种技术。
     * 3、每个客户端都有自己的一个 Session 会话。
     * 4、Session 会话中，我们经常用来保存用户登录之后的信息。
     * j) 如何创建 Session 和获取(id 号,是否为新)
     * request.getSession() 第一次调用时：创建 Session 会话
     * 之后调用都是：获取前面创建好的 Session 会话对象。
     * isNew(); 判断到底是不是刚创建出来的（新的） true 表示刚创建 false 表示获取之前创建
     * 每个会话都有一个身份证号。也就是 ID 值。而且这个 ID 是唯一的。 getId() 得到 Session 的会话 id 值。
     */
    protected void createOrGetSession(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 创建session,本质服务器创建了session，同时给客户端添加了cookie，即添加了响应头 Set-Cookie: JSESSIONID=E4D9E49612A1A48C7C1D7B9EFD031FBC; Path=/lishuoboy_javaweb_war_exploded; HttpOnly
        HttpSession session = req.getSession();
        String sessionId = session.getId();
        String reqSessionId = req.getRequestedSessionId();
        boolean isNew = session.isNew();
        resp.getWriter().write(StrUtil.format("""
            <pre>
            sessionId=={}\n
            reqSessionId=={}\n
            session.isNew()=={}
            </pre>""", sessionId, reqSessionId, isNew));
    }

    /** 往 Session 中保存数据 */
    protected void setAttribute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getSession().setAttribute("name1", "值111, 随机数：" + RandomUtil.randomNumber());
        resp.getWriter().write("已经往 Session 中保存了数据");
    }

    /** 获取 Session 域中的数据 */
    protected void getAttribute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Object attribute = req.getSession().getAttribute("name1");
        resp.getWriter().write("从 Session 中获取出 name1 的数据是：" + attribute);
    }

    /**
     * Session 的默认超时时长及配置
     * session 的超时指的是：客户端两次请求的最大间隔时长。
     */
    protected void defaultLife(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        HttpSession session = req.getSession();
        // session默认超时时间是tomcat中的为30分钟
        // 如果说你希望你的 web 工程，默认的 Session 的超时时长为其他时长。你可以在你自己的 web.xml 配置文件中做 以上相同的配置。就可以修改你的 web 工程所有 Seession 的默认超时时长
//        <session-config>
//            <session-timeout>20</session-timeout>
//        </session-config>
        resp.getWriter().write("session超时时间：" + session.getMaxInactiveInterval() + " 秒");
    }

    /** 如果你想只修改个别 Session 的超时时长，就可以使用 setMaxInactiveInterval(int interval)来进行单独的设置。 */
    protected void life3(HttpServletRequest req, HttpServletResponse resp) throws IOException { // 先获取 Session 对象
        HttpSession session = req.getSession(); // 设置当前 Session 3 秒后超时
        log.info("session.isNew()=={}", session.isNew());
        session.setMaxInactiveInterval(3);
        resp.getWriter().write("当前 Session 已经设置为 3 秒后超时");
    }

    /** Session 立即失效 */
    protected void deleteNow(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 先获取 Session 对象
        HttpSession session = req.getSession();
        // 让 Session 会话马上超时
        session.invalidate();
        resp.getWriter().write("Session 已经设置为超时（无效）");
    }

    /** 登录 */
    protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getParameter("name");
        String pwd = req.getParameter("pwd");
        if ("lishuo".equalsIgnoreCase(name) & "111111".equals(pwd)) {
            req.getSession().setAttribute("user", new User().setName(name).setPwd(pwd));
            req.getSession().setMaxInactiveInterval(5); // 默认30分钟超时，改为5秒测试用
        } else {
            req.getSession().setAttribute("loginMsg", "登录失败");
        }
        resp.sendRedirect("13cookie_session/session_index.jsp");
    }

    /** 登出（主动） */
    protected void logout(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getSession().invalidate();  // 让 Session 会话马上超时
        resp.sendRedirect("13cookie_session/session_login.html");
    }
}